package cn.ytr.crm.service.impl;

import cn.ytr.crm.domain.Employee;
import cn.ytr.crm.domain.Permission;
import cn.ytr.crm.mapper.EmployeeMapper;
import cn.ytr.crm.mapper.PermissionMapper;
import cn.ytr.crm.query.PageResult;
import cn.ytr.crm.query.QueryObject;
import cn.ytr.crm.service.IPermissionService;
import cn.ytr.crm.util.UserContext;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class PermissionServiceImpl implements IPermissionService{

	@Autowired
	private PermissionMapper permissionMapper;
	@Autowired
	private EmployeeMapper employeeMapper;
	@Autowired
	private ApplicationContext applicationContext;

	/**
	 * 增加或保存权限
	 */
	@Override
	public void saveOrUpate(Permission permission) {
		if (permission.getId() != null) {
			permissionMapper.updateByPrimaryKey(permission);
		} else {
			permissionMapper.insert(permission);
		}
	}

	/**
	 * 删除某个权限
	 */
	@Override
	public void delete(Long id) {
		permissionMapper.deleteByPrimaryKey(id);
		//维护 角色权限中间表，删除某个权限也应该把对应的记录删掉
        permissionMapper.deleteRelation(id);
	}

	/**
	 * 获取单个权限
	 */
	@Override
	@Transactional(readOnly=true)
	public Permission get(Long id) {
		Permission permission = permissionMapper.selectByPrimaryKey(id);
		return permission;
	}

	/**
	 * 获取所有权限
	 */
	@Override
	@Transactional(readOnly=true)
	public List<Permission> listAll() {
		List<Permission> list = permissionMapper.selectAll();
		return list;
	}

	/**
	 * 高级查询所有权限
	 */
	@Override
	@Transactional(readOnly=true)
	public PageResult query(QueryObject qo) {
		Integer count = permissionMapper.selectForCount(qo);
		if (count < 1 || count == null) {
			return new PageResult(qo.getPageSize());
		} else {
			List<Permission> list = permissionMapper.selectForList(qo);
			return new PageResult(qo.getCurrentPage(), count, list, qo.getPageSize());
		}
	}

    /**
     * 重新加载（自动检测并且更新权限表）做的其实就是检测有哪些操作，然后就新增给权限表
     */
    public void onload() {
        //原权限数据表所有的权限
        List<String> permissionExpressions = permissionMapper.selectAllExpression();
        System.out.println(permissionExpressions);

        /*从 sping 容器 ApplicationContext 获取到所有贴有我们权限注解的 bean（控制器类反射）
        然后遍历所有方法，判断方法里有没有贴注解，有则用注解里的属性处理权限表
        */
        Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(Controller.class);
        //返回的 map 里只有 value 是我们想要 bean，所以我们还要进一步抽取
        Collection<Object> beans = beansWithAnnotation.values();
        //遍历 beans
        for (Object bean : beans) {
            //获取字节码对象
            //Class<?> beanClass = bean.getClass();
            Class<?> beanClass = bean.getClass().getSuperclass(); //shiro：从父类字节码获取（因为用了代理 cglib ，代理类是继承控制器类，获取不了父类的注解）
            //获取字节码对象里的所有方法
            Method[] methods = beanClass.getDeclaredMethods();
            //遍历方法，看有没有贴注解
            for (Method method : methods) {
                //自定义的权限注解
                //RequiredPermission annotation = method.getAnnotation(RequiredPermission.class);
                //shiro 的权限注解
                RequiresPermissions annotation = method.getAnnotation(RequiresPermissions.class);   //shiro
                //有贴该注解就做处理
                if (annotation != null){
                    //如果权限数据表里没有改权限，我们才新增
                    //String expression = annotation.expression();
                    String expression = annotation.value()[1];  //shiro
                    if (!permissionExpressions.contains(expression)) {
                        //用注解中的属性封装权限对象
                        //Permission permission = new Permission(null, annotation.name(), annotation.expression()); //shiro
                        Permission permission = new Permission(null, annotation.value()[0], expression);
                        permissionMapper.insert(permission);
                    }
                }
            }
        }

    }

	/**
	 * 通过员工 id 获取所有权限
	 */
	public List<String> selectByEmpId(Long id) {
		List<String> permissions = permissionMapper.selectByEmpId(id);
		return permissions;
	}

	/**
	 * 更新 session 里的用户权限
	 */
	public void refreshSelfPermisson() {
		Employee employee = employeeMapper.selectByPrimaryKey(UserContext.getCurrentUser().getId());
		//更新 session 里的 超管权限
		UserContext.setCurrentUser(employee);
		//更新 session 里的当前用户的角色权限
		UserContext.setCurrentUserPermission(permissionMapper.selectByEmpId(employee.getId()));
	}

}
